#pragma once

#include "Http.hpp"
#include <iostream>
#include <string>
#include <unordered_map>
#include <fstream>
#include <functional>
#include <memory>

using namespace Http_ns;

using func_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class HttpService
{
private:
    // 读取html文件的内容，用于发送给客户端
    std::string GetFileContent(const std::string &path)
    {
        // 以二进制读文件
        std::ifstream in(path, std::ios::binary);
        if (!in.is_open())
            return std::string();

        // 获取文件大小

        // 将光标移动到文件末尾
        in.seekg(0, in.end);
        // 得到光标的偏移量，从而得到文件大小
        int filesize = in.tellg();
        // 再将光标移动到开头，进行写入
        in.seekg(0, in.beg);

        // 读入数据
        std::string content;
        content.resize(filesize);
        in.read((char*)content.c_str(), filesize);
        in.close();

        return content;
    }

public:
    HttpService()
    {
        _mime_type.insert(std::make_pair(".html", "text/html"));
        _mime_type.insert(std::make_pair(".default", "text/html"));

        _code_to_desc.insert(std::make_pair(100, "Continue"));
        _code_to_desc.insert(std::make_pair(200, "OK"));
        _code_to_desc.insert(std::make_pair(201, "Created"));
        _code_to_desc.insert(std::make_pair(301, "Moved Permanently"));
        _code_to_desc.insert(std::make_pair(302, "Found"));
        _code_to_desc.insert(std::make_pair(404, "Not Found"));
    }

    std::string HanderHttpRequest(std::string &reqstr)
    {
        std::cout << "---------------------------------------" << std::endl;
        std::cout << reqstr;
        std::cout << "---------------------------------------" << std::endl;

        auto req = Factory::BuildRequestDefault();
        auto resp = Factory::BuildResponseDefault();

        req->DeSerialize(reqstr);

        std::string content = GetFileContent(req->Path());
        if (content.empty())
        {
            content = GetFileContent("wwwroot/404.html");
            resp->AddCode(404, _code_to_desc[404]);
            resp->AddHeader("Content-Length", std::to_string(content.size()));
            resp->AddHeader("Content-Type", _mime_type[".html"]);
            resp->AddBodyText(content);
        }
        else
        {
            resp->AddCode(200, _code_to_desc[200]);
            resp->AddHeader("Content-Length", std::to_string(content.size()));
            resp->AddHeader("Content-Type", _mime_type[req->Suffix()]);
            resp->AddHeader("Set-Cookie", "username=zhangsan");
            // resp.AddHeader("Set-Cookie", "passwd=12345");
            resp->AddBodyText(content);
        }

        return resp->Serialize();
    }

private:
    std::unordered_map<std::string, std::string> _mime_type; // 对应文件后缀代表的不同的文件类型
    std::unordered_map<int, std::string> _code_to_desc;      // 状态码和状态码描述
    std::unordered_map<std::string, func_t> _service_list;   // 执行的任务
};